package com.ck.core.ffmpeg;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

/**
 * 命令行类
 *
 * @author linqiang
 * @version v1.0
 * @Description
 * @date 2019-04-18 15:36
 */
public class FfmpegCommand {

    private Logger logger = LoggerFactory.getLogger(FfmpegCommand.class);

    private List<String> command;

    public FfmpegCommand(List<String> command) {
        this.command = command == null ? new ArrayList<>() : command;
    }

    public List<String> getCommand() {
        return command;
    }

    public void setCommand(List<String> command) {
        this.command = command;
    }

    /**
     * 开始执行命令
     */
    public void start() throws FfmpegCommandException {
        InputStream es = null;
        InputStreamReader isr = null;
        BufferedReader br = null;
        Process process = null;
        try {
            ProcessBuilder builder = new ProcessBuilder();
            logger.info("*** 执行方法1");
            builder.command(command);
            //开启执行子线程
            logger.info("*** 执行方法2");
            process = builder.start();
            // 使用这种方式会在瞬间大量消耗CPU和内存等系统资源，所以这里我们需要对流进行处理
            es = process.getErrorStream();
            isr = new InputStreamReader(es);
            br = new BufferedReader(isr);
            logger.info("*** 执行方法3");
            String line = null;
            while ((line = br.readLine()) != null) {
//                logger.info(line);
            }
            logger.info("*** 执行方法4");
        } catch (IOException e) {
            logger.error(e.getMessage(),e);
            throw new FfmpegCommandException(e.getMessage(), e);
        } finally {
            close(es, isr, br, process);
        }
    }

    /**
     * 开始执行命令
     *
     * @return 命令的信息输出String
     */
    public String startReturnString() throws FfmpegCommandException {
        InputStream es = null;
        InputStreamReader isr = null;
        BufferedReader br = null;
        StringBuilder sbf = new StringBuilder();
        String resultInfo = null;
        Process process = null;
        try {
            ProcessBuilder builder = new ProcessBuilder();
            builder.command(command);
            //开启执行子线程
            process = builder.start();
            // 使用这种方式会在瞬间大量消耗CPU和内存等系统资源，所以这里我们需要对流进行处理
            es = process.getErrorStream();
            isr = new InputStreamReader(es);
            br = new BufferedReader(isr);
            String line = null;
            while ((line = br.readLine()) != null) {
                sbf.append(line);
                sbf.append("\n");
            }
            resultInfo = sbf.toString();
        } catch (IOException e) {
            throw new FfmpegCommandException( e.getMessage(), e);
        } finally {
            close(es, isr, br, process);
        }
        return resultInfo;
    }

    /**
     * 开始执行命令
     *
     * @return 命令的信息输出List
     */
    public List<String> startReturnList() throws FfmpegCommandException {
        InputStream es = null;
        InputStreamReader isr = null;
        BufferedReader br = null;
        List<String> resultInfo = new ArrayList<>();
        Process process = null;
        try {
            ProcessBuilder builder = new ProcessBuilder();
            builder.command(command);
            //开启执行子线程
            process = builder.start();
            // 使用这种方式会在瞬间大量消耗CPU和内存等系统资源，所以这里我们需要对流进行处理
            es = process.getErrorStream();
            isr = new InputStreamReader(es);
            br = new BufferedReader(isr);
            String line = null;
            while ((line = br.readLine()) != null) {
                resultInfo.add(line);
//                logger.info(line);
            }
        } catch (IOException e) {
            throw new FfmpegCommandException( e.getMessage(), e);
        } finally {
            close(es, isr, br, process);
        }
        return resultInfo;
    }

    /**
     * 关闭相关流或进程
     *
     * @param es
     * @param isr
     * @param br
     * @param process
     */
    private void close(InputStream es, InputStreamReader isr, BufferedReader br, Process process) {
        try {
            if (br != null) {
                br.close();
            }
            if (isr != null) {
                isr.close();
            }
            if (es != null) {
                es.close();
            }
            if (process != null) {
                process.destroy();
            }
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
        }
    }
}
